#pragma once
#ifndef CLIB_TUPLE_HASH_H
#define CLIB_TUPLE_HASH_H

#include "clib_type.h"
#include "clib_queue.h"
#include "clib_spinlock.h"
#include "clib_sock.h"
#include <rte_rwlock.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct hash_node_s
{
    clib_spinlock_t lock;
    clib_queue_t    list;
}hash_node_t;

typedef u32_t (*hash_fn)(void *key,i32_t key_len);

typedef u32_t (*equal_fn)(void* key1,void* key2,i32_t key_len);

typedef struct clib_tuple_table_s
{
    u32_t           bins;
    u32_t           need_lk;
    hash_fn         hash;
    equal_fn        eqfn;
    hash_node_t     node[];
} clib_tuple_table_t;

clib_tuple_table_t*
clib_tuple_hash_table_create(hash_fn hash,equal_fn eqfn,u32_t bins,u32_t is_lk,i32_t socket_id);

void
clib_tuple_hash_table_destroy(clib_tuple_table_t *ht);

void*
clib_tuple_hash_table_search(clib_tuple_table_t *ht,void *key,i32_t ipv4);

u32_t
clib_tuple_hash_table_remove(clib_tuple_table_t *ht,clib_sock_t *sock);

u32_t
clib_tuple_hash_table_insert(clib_tuple_table_t *ht,clib_sock_t *node);

u32_t
clib_tuple_jshash(const void *key, i32_t len);

i32_t
clib_tuple_equal(const void *key1, const void *key2, i32_t len);

#ifdef __cplusplus
}
#endif

#endif